// app/api/evaluation/attachments/[id]/route.ts import { NextRequest, NextResponse } from "next/server"; import db from "@/db/db"; import { reviewerEvaluationAttachments } from "@/db/schema"; import { eq } from "drizzle-orm"; import { getServerSession } from "next-auth/next" import { authOptions } from "@/app/api/auth/[...nextauth]/route" import { deleteFile } from "@/lib/file-stroage"; interface Context { params: { id: string; }; } // 첨부파일 삭제 export async function DELETE( request: NextRequest, { params }: Context ) { try { // 인증 확인 const session = await getServerSession(authOptions); if (!session?.user?.id) { return NextResponse.json( { success: false, error: "인증이 필요합니다." }, { status: 401 } ); } const attachmentId = parseInt(params.id); if (isNaN(attachmentId)) { return NextResponse.json( { success: false, error: "유효하지 않은 첨부파일 ID입니다." }, { status: 400 } ); } const result = await db.transaction(async (tx) => { // 1. 첨부파일 정보 조회 const attachment = await tx .select({ id: reviewerEvaluationAttachments.id, publicPath: reviewerEvaluationAttachments.publicPath, uploadedBy: reviewerEvaluationAttachments.uploadedBy, }) .from(reviewerEvaluationAttachments) .where(eq(reviewerEvaluationAttachments.id, attachmentId)) .limit(1); if (attachment.length === 0) { throw new Error("첨부파일을 찾을 수 없습니다."); } // 2. 권한 확인 (업로드한 사용자만 삭제 가능) if (attachment[0].uploadedBy !== parseInt(session.user.id)) { throw new Error("삭제 권한이 없습니다."); } // 3. DB에서 첨부파일 정보 삭제 await tx .delete(reviewerEvaluationAttachments) .where(eq(reviewerEvaluationAttachments.id, attachmentId)); // 4. 물리적 파일 삭제 try { await deleteFile(attachment[0].publicPath); } catch (fileError) { console.warn("물리적 파일 삭제 실패:", fileError); // 파일 삭제 실패는 DB 삭제를 롤백하지 않음 } return true; }); return NextResponse.json({ success: true, message: "첨부파일이 삭제되었습니다.", }); } catch (error) { console.error("첨부파일 삭제 실패:", error); return NextResponse.json( { success: false, error: error instanceof Error ? error.message : "첨부파일 삭제 중 오류가 발생했습니다.", }, { status: 500 } ); } } // 특정 첨부파일 정보 조회 export async function GET( request: NextRequest, { params }: Context ) { try { const session = await getServerSession(authOptions); if (!session?.user?.id) { return NextResponse.json( { success: false, error: "인증이 필요합니다." }, { status: 401 } ); } const attachmentId = parseInt(params.id); if (isNaN(attachmentId)) { return NextResponse.json( { success: false, error: "유효하지 않은 첨부파일 ID입니다." }, { status: 400 } ); } const attachment = await db .select({ id: reviewerEvaluationAttachments.id, originalFileName: reviewerEvaluationAttachments.originalFileName, publicPath: reviewerEvaluationAttachments.publicPath, fileSize: reviewerEvaluationAttachments.fileSize, mimeType: reviewerEvaluationAttachments.mimeType, description: reviewerEvaluationAttachments.description, createdAt: reviewerEvaluationAttachments.createdAt, }) .from(reviewerEvaluationAttachments) .where(eq(reviewerEvaluationAttachments.id, attachmentId)) .limit(1); if (attachment.length === 0) { return NextResponse.json( { success: false, error: "첨부파일을 찾을 수 없습니다." }, { status: 404 } ); } return NextResponse.json({ success: true, attachment: attachment[0], }); } catch (error) { console.error("첨부파일 조회 실패:", error); return NextResponse.json( { success: false, error: "첨부파일 조회 중 오류가 발생했습니다.", }, { status: 500 } ); } }